<?php

Wind::import('ADMIN:library.AdminBaseController');
Wind::import('SRV:tag.dm.PwTagDm');

/**
 * 话题后台.
 *
 * @author jinlong.panjl <jinlong.panjl@aliyun-inc.com>
 * @copyright ©2003-2103 phpwind.com
 * @license http://www.phpwind.com
 *
 * @version $Id$
 */
class ManageController extends AdminBaseController
{
    private $perpage = 10;

    public function beforeAction($handlerAdapter)
    {
        parent::beforeAction($handlerAdapter);
        $this->setOutput($handlerAdapter->getControllerKey(), 'controllerKey');
        $this->setOutput($handlerAdapter->getModuleKey(), 'moduleKey');
    }

    /* (non-PHPdoc)
     * @see WindController::run()
     */
    public function run()
    {
        $conditions = array('page', 'keyword', 'ifhot', 'categoryId', 'minAttention', 'maxAttention', 'minContent', 'maxContent');
        list($page, $keyword, $ifhot, $categoryId, $minAttention, $maxAttention, $minContent, $maxContent) = $this->getInput($conditions);
        $categories = $this->_getTagCateGoryDs()->getAllCategorys();
        $this->setOutput($categories, 'categories');
        //搜索话题
        $page = intval($page);
        $page < 1 && $page = 1;
        strlen($ifhot) or $ifhot = -1;
        list($start, $limit) = Pw::page2limit($page, $this->perpage);
        list($count, $tags) = $this->_getTagService()->getTagByCondition($start, $limit, $keyword, $ifhot, $categoryId, $minAttention, $maxAttention, $minContent, $maxContent);
        $maxPage = ceil($count / $this->perpage);
        if ($page > $maxPage) {
            $page = $maxPage;
            list($start, $limit) = Pw::page2limit($page, $this->perpage);
            list($count, $tags) = $this->_getTagService()->getTagByCondition($start, $limit, $keyword, $ifhot, $categoryId, $minAttention, $maxAttention, $minContent, $maxContent);
        }
        $tags = $this->_buildTagData($tags, $categories);
        $args = array();
        foreach ($conditions as $v) {
            if ($v == 'page') {
                continue;
            }
            $this->setOutput($$v, $v);
            $args[$v] = $$v;
        }
        $this->setOutput($tags, 'tags');
        //pagination
        $this->setOutput($page, 'page');
        $this->setOutput($count, 'count');
        $this->setOutput($args, 'args');
        $this->setOutput($this->perpage, 'perPage');
        //$this->setOutput(ceil($count/$this->perpage), 'totalpage');
    }

    public function addAction()
    {
        $categories = $this->_getTagCateGoryDs()->getAllCategorys();
        $this->setOutput($categories, 'categories');
    }

    /**
     * 保存添加的话题.
     */
    public function doaddAction()
    {
        $tag = $this->getInput('tag');
        if (!$tag['name']) {
            $this->showError('Tag:tagname.empty');
        }
        if ($this->_getTagDs()->getTagByName($tag['name'])) {
            $this->showError("话题{$tag['name']}已存在");
        }
        $tag = $this->getInput('tag');
        $logo = $this->uploadLogo();
        $dm = new PwTagDm();
        $dm->setName($tag['name'])
            ->setTagLogo($logo)
            ->setTypeId(PwTag::TYPE_THREAD_TOPIC)
            ->setIfhot(1)
            ->setCreateUid($this->loginUser->uid)
            ->setExcerpt($tag['excerpt'])
            ->setSeoTitle($tag['seo_title'])
            ->setSeoDescript($tag['seo_description'])
            ->setSeoKeywords($tag['seo_keywords']);
        $logo && $dm->setIflogo(1);
        if (is_numeric($tagId = $this->_getTagDs()->addTag($dm))) {
            // 话题内容关系
            $tag['category'] && $this->_getTagCateGoryDs()->addCategoryRelations($tagId, $tag['category']);
            //关联话题
            if ($tag['relate_tags']) {
                $tagNames = explode(',', $tag['relate_tags']);
                foreach ($tagNames as $v) {
                    $this->_addRelateTag($tagId, $v);
                }
            }
            $this->_deleteHotTagCache();
            $this->showMessage('话题添加成功！');
        } else {
            if ($tagId instanceof PwError) {
                $this->showError($tagId->getError());
            }
            $this->showError('话题添加失败！');
        }
    }

    /**
     * 编辑话题.
     */
    public function editAction()
    {
        $tagId = intval($this->getInput('id', 'get'));
        $tag = $this->_getTagDs()->getTag($tagId);
        $categories = $this->_getTagCateGoryDs()->getAllCategorys();
        //取关联话题
        $relatedTag = $this->_getTagDs()->getTagByParent($tagId);
        if ($relatedTag) {
            $relatedTagHtml = array();
            foreach ($relatedTag as $v) {
                $relatedTagHtml[] = $v['tag_name'];
            }
            $this->setOutput(implode(',', $relatedTagHtml), 'relatedTags');
        }
        //话题分类
        $tagCategories = $this->_getTagCateGoryDs()->getCategoriesByTagId($tagId);
        $tagCategories and $this->setOutput($tagCategories, 'tagCategories');
        $this->setOutput($tag, 'tag');
        $this->setOutput($categories, 'categories');
    }

    /**
     * 保存话题.
     */
    public function doeditAction()
    {
        $tag = $this->getInput('tag');
        if (!$tag['name']) {
            $this->showError('Tag:tagname.empty');
        }
        $tagInfo = $this->_getTagDs()->getTag($tag['tag_id']);
        if (!$tagInfo) {
            $this->showError('话题不存在！');
        }
        $logo = $this->uploadLogo();
        $dm = new PwTagDm($tag['tag_id']);
        $dm->setName($tag['name'])
            ->setExcerpt($tag['excerpt'])
            ->setSeoTitle($tag['seo_title'])
            ->setSeoDescript($tag['seo_description'])
            ->setSeoKeywords($tag['seo_keywords']);
        if ($logo) {
            $dm->setTagLogo($logo)
                ->setIflogo(1);
        }
        if ($logo && $logo != $tagInfo['tag_logo']) {
            Pw::deleteAttach($tagInfo['tag_logo']);
        }
        //取消原关联话题

        $this->_getTagService()->removeRelatedTopic($tag['tag_id']);
        if ($tag['relate_tags']) {
            $tagInfo = $this->_getTagDs()->getTag($tag['tag_id']);
            $tagInfo['parent_tag_id'] && $this->showError(sprintf('话题"%s"已经有关联话题,不允许再合并关联', $tagInfo['tag_name']));
            $tagNames = explode(',', $tag['relate_tags']);
            foreach ($tagNames as $v) {
                $mergeTag = $this->_getTagDs()->getTagByName($v);
                if ($mergeTag['parent_tag_id']) {
                    $parentTag = $this->_getTagDs()->getTag($mergeTag['parent_tag_id']);
                    $this->showError(sprintf('话题"%s"的关联话题为%s,不允许再合并关联', $mergeTag['tag_name'], $parentTag['tag_name']));
                }
                $this->_addRelateTag($tag['tag_id'], $v);
            }
        }
        $this->_getTagCateGoryDs()->updateCategoryRelations($tag['tag_id'], $tag['category']);
        $result = $this->_getTagDs()->updateTag($dm);
        if ($result instanceof PwError) {
            $this->showError($result->getError());
        }
        $this->_deleteHotTagCache();
        $this->showMessage('话题编辑成功！');
    }

    /**
     * 合并关联话题.
     */
    public function mergeAction()
    {
    }

    /**
     * 删除话题.
     */
    public function deleteAction()
    {
        $tagIds = $this->getInput('tag_id', 'post');
        is_array($tagIds) or $tagIds = explode(',', $tagIds);
        if (!$tagIds) {
            $this->showError('operate.select');
        }
        $this->_getTagService()->deleteByTagIds($tagIds);
        $this->_deleteHotTagCache();
        $this->showMessage('话题删除成功！');
    }

    /**
     * 取消热门话题.
     */
    public function deletehotAction()
    {
        $tagIds = $this->getInput('tag_id');
        if (!$tagIds) {
            $this->showError('operate.select');
        }
        foreach ($tagIds as $tagId) {
            $dm = new PwTagDm($tagId);
            $dm->setIfhot(0);
            $this->_getTagDs()->updateTag($dm);
        }
        //删除update表
        $this->_getTagDs()->deleteTagRecords($tagIds);
        $this->_deleteHotTagCache();
        $this->showMessage('ADMIN:success');
    }

    /**
     * 设置热门话题.
     */
    public function sethotAction()
    {
        $tagIds = $this->getInput('tag_id');
        if (!$tagIds) {
            $this->showError('operate.select');
        }
        $time = Pw::getTime();
        foreach ($tagIds as $tagId) {
            $dm = new PwTagDm($tagId);
            $dm->setIfhot(1);
            $this->_getTagDs()->updateTag($dm);
            $this->_getTagDs()->addTagRecord($tagId, $time);
        }
        //删除update表
        $this->_deleteHotTagCache();
        $this->showMessage('ADMIN:success');
    }

    /**
     * 合并关联话题.
     */
    public function domergeAction()
    {
        $tagIds = explode(',', $this->getInput('tag_id', 'post'));
        $tagName = $this->getInput('tag_name', 'post');
        if (!$tagIds || !$tagName) {
            $this->showError('请输入关联话题名称');
        }
        $tag = $this->_getTagDs()->getTagByName($tagName);
        //检查待合并的TAG有无所属话题
        $checkTags = $this->_getTagDs()->fetchTag($tagIds);
        foreach ($checkTags as $v) {
            $parentTag = $this->_getTagDs()->getTag($v['parent_tag_id']);
            $parentTag && $this->showError(sprintf('话题"%s"已经合并到话题"%s",不允许再合并到其他话题', $v['tag_name'], $parentTag['tag_name']));
            $tagInfo = $this->_getTagDs()->getTagByParent($v['tag_id']);
            $tagInfo && $this->showError(sprintf('话题"%s"已经存在合并话题"%s",不允许被合并到其他话题', $v['tag_name'], $tagInfo['tag_name']));
        }
        if (!$tag) {
            $dm = new PwTagDm();
            $dm->setName($tagName);
            $toTagId = $this->_getTagDs()->addTag($dm);
        } else {
            $toTagId = $tag['tag_id'];
            if ($tag['parent_tag_id']) {
                $parentTag = $this->_getTagDs()->getTag($tag['parent_tag_id']);
                $this->showError(sprintf('话题"%s"已经合并到话题"%s",不允许合并其他话题', $tag['tag_name'], $parentTag['tag_name']));
            }
        }
        foreach ($tagIds as $tagId) {
            $this->_mergeTags($tagId, $toTagId);
        }
        $this->_deleteHotTagCache();
        $this->showMessage('合并关联话题成功！');
    }

    /**
     * 移动分类.
     */
    public function moveAction()
    {
        $categories = $this->_getTagCateGoryDs()->getAllCategorys();
        $this->setOutput($categories, 'categories');
    }

    /**
     * 移动分类.
     */
    public function domoveAction()
    {
        $tagIds = explode(',', $this->getInput('tag_id'));
        $categoryIds = $this->getInput('category_ids');
        if (!$tagIds || !$categoryIds) {
            $this->showError('operate.select');
        }
        if (count($categoryIds) > 1) {
            $key = array_search(0, $categoryIds);
            if ($key !== false) {
                unset($categoryIds[$key]);
            }
        }
        foreach ($tagIds as $tagId) {
            $this->_getTagCateGoryDs()->updateCategoryRelations($tagId, $categoryIds);
        }
        $this->_deleteHotTagCache();
        $this->showMessage('操作成功');
    }

    /**
     * 话题分类列表.
     */
    public function categoryAction()
    {
        $categorys = $this->_getTagCateGoryDs()->getCategorysWithCount();
        $this->setOutput($categorys, 'categorys');
    }

    /**
     * 编辑分类.
     */
    public function editCategoryAction()
    {
        $id = $this->getInput('id');
        $category = $this->_getTagCateGoryDs()->getCategoryById($id);
        $this->setOutput($category, 'category');
    }

    /**
     * 提交编辑.
     */
    public function doEditCategoryAction()
    {
        $data = $this->getInput('data');
        $id = (int) $this->getInput('id');
        $result = $this->_checkWork($data['alias']);
        if ($result !== true) {
            $this->showError($result);
        }
        $dm = new PwTagDm($id);
        $dm->setCategoryName($data['category_name'])
            ->setCategoryAlias($data['alias'])
            ->setVieworder($data['vieworder'])
            ->setSeoDescript($data['seo_description'])
            ->setSeoKeywords($data['seo_keywords'])
            ->setSeoTitle($data['seo_title']);
        $this->_getTagCateGoryDs()->updateTagCategory($dm);
        $this->showMessage('success');
    }

    /**
     * 设置分类列表.
     */
    public function setCategoryAction()
    {
        list($data, $newdata) = $this->getInput(array('data', 'newdata'));
        $allCategorys = $this->_getTagCateGoryDs()->getAllCategorys();
        $categorys = array();
        foreach ($allCategorys as $v) {
            $categorys[$v['category_id']] = $v['category_name'];
        }
        if ($data) {
            foreach ($data as $v) {
                unset($categorys[$v['category_id']]);
                $aliasWord = $this->_checkWork($v['alias']);
                if ($aliasWord !== true) {
                    $this->showError($aliasWord);
                }
                if (in_array($v['category_name'], $categorys)) {
                    continue;
                }
                $categorys[$v['category_id']] = $v['category_name'];
                $dm = new PwTagDm($v['category_id']);
                $dm->setCategoryName($v['category_name'])
                    ->setCategoryAlias($v['alias'])
                    ->setVieworder($v['vieworder']);
                if (($result = $this->_getTagCateGoryDs()->updateTagCategory($dm)) instanceof PwError) {
                    $this->showError($result->getError());
                }
            }
        }
        if ($newdata) {
            foreach ($newdata as $v) {
                $aliasWord = $this->_checkWork($v['alias']);
                if ($aliasWord !== true) {
                    $this->showError($aliasWord);
                }
                if (in_array($v['category_name'], $categorys)) {
                    continue;
                }
                $dm = new PwTagDm();
                $dm->setCategoryName($v['category_name'])
                    ->setCategoryAlias($v['alias'])
                    ->setVieworder($v['vieworder']);
                if (($result = $this->_getTagCateGoryDs()->addTagCategory($dm)) instanceof PwError) {
                    $this->showError($result->getError());
                }
            }
        }
        $this->showMessage('success');
    }

    public function deleteCategoryAction()
    {
        $id = $this->getInput('id', 'post');
        if (!$id) {
            $this->showError('operate.fail');
        }
        $this->_getTagCateGoryDs()->deleteCategory($id);
        $this->showMessage('success');
    }

    private function _mergeTags($fromTagId, $toTagId)
    {
        $fromTag = $this->_getTagDs()->getTag($fromTagId);
        if ($fromTag['parent_tag_id']) {
            return false;
        }
        //from
        $dm = new PwTagDm($fromTagId);
        $dm->setParent($toTagId)
            ->setContentCount(0)
            ->setAttentionCount(0);
        $this->_getTagDs()->updateTag($dm);
        //to
        $dm = new PwTagDm($toTagId);
        $dm->addContentCount($fromTag['content_count'])
            ->addAttentionCount($fromTag['attention_count']);
        $this->_getTagDs()->updateTag($dm);
        //update content relation
        $this->_getTagDs()->updateTagRelationByTagId($fromTagId, $toTagId);
        //update update log
        $this->_getTagDs()->updateTagRecordByTagId($fromTagId, $toTagId);
    }

    private function _deleteHotTagCache()
    {
        $allCategorys = $this->_getTagCateGoryDs()->getAllCategorys();
        $keys = array('hot_tags_0');
        foreach ($allCategorys as $v) {
            $keys[] = sprintf('hot_tags_%s', $v['category_id']);
        }
        Wekit::cache()->batchDelete($keys);
    }

    private function _checkWork($str)
    {
        if (!$str) {
            return true;
        }
        if (0 >= preg_match('/^[A-Za-z]+$/', $str)) {
            return 'TAG:charset.error';
        }

        return true;
    }

    /**
     * 添加关联话题.
     *
     * @param int    $tagId   关联到哪个话题Id
     * @param string $tagName 话题名称
     */
    private function _addRelateTag($tagId, $tagName)
    {
        $tagId = intval($tagId);
        if ($tagId < 1 || !$tagName) {
            return false;
        }
        $tag = $this->_getTagDs()->getTag($tagId);
        if (!$tag) {
            return false;
        }
        $relateTag = $this->_getTagDs()->getTagByName($tagName);
        if (!$relateTag) {
            $dm = new PwTagDm();
            $dm->setName($tagName)
                ->setCreateUid($this->loginUser->uid)
                ->setParent($tagId);
            $this->_getTagDs()->addTag($dm);
        } else {
            if ($relateTag['tag_id'] == $tagId) {
                return false;
            }
            //检查被关联的话题是否存在子话题
            if ($this->_getTagDs()->getTagByParent($relateTag['tag_id'])) {
                return false;
            }
            $dm = new PwTagDm($relateTag['tag_id']);
            $dm->setParent($tagId);
            $this->_getTagDs()->updateTag($dm);
        }

        return true;
    }

    /**
     * 组装tags数据.
     *
     * @param array $tags
     */
    private function _buildTagData($tags, $categories)
    {
        if (!is_array($tags)) {
            return array();
        }
        foreach ($tags as $k => $v) {
            if (!$v['categories']) {
                continue;
            }
            $tmpCategoryNames = array();
            foreach ($v['categories'] as $v2) {
                $tmpCategoryNames[] = $categories[$v2]['category_name'];
            }
            $tags[$k]['categories'] = implode(',', $tmpCategoryNames);
        }

        return $tags;
    }

    /**
     * 上传话题图标.
     *
     * @return string
     */
    private function uploadLogo()
    {
        Wind::import('SRV:upload.action.PwTagUpload');

        $tagUpload = new PwTagUpload(156, 156);
        $upload = new PwUpload($tagUpload);
        if (($result = $upload->check()) === true) {
            $result = $upload->execute();
        }
        if ($result !== true) {
            $this->showError($result->getError());
        }

        return $tagUpload->getPath();
    }

    /**
     * @return PwTagService
     */
    private function _getTagService()
    {
        return Wekit::load('tag.srv.PwTagService');
    }

    /**
     * @return PwTag
     */
    private function _getTagDs()
    {
        return Wekit::load('tag.PwTag');
    }

    /**
     * @return PwTagAttention
     */
    private function _getTagAttentionDs()
    {
        return Wekit::load('tag.PwTagAttention');
    }

    /**
     * 分类DS.
     *
     * @return PwTagCateGory
     */
    private function _getTagCateGoryDs()
    {
        return Wekit::load('tag.PwTagCateGory');
    }
}
